package org.report4service.views;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;

import org.report4service.listeners.AlertMessageListener;
import org.report4service.listeners.LogonListner;
import org.report4service.listeners.StorageListener;
import org.report4service.midlet.Report4Service;
import org.report4service.model.User;
import org.report4service.services.ReportServiceImpl;
import org.report4service.services.UserServiceImpl;
import org.report4service.utils.AlertMessage;
import org.report4service.utils.CommandPool;
import org.report4service.utils.TextPool;

/**
 * Form where user enters his/her password before accessing the application
 * 
 * @author Jmpango
 * 
 */
public class LoginForm extends Form implements CommandListener, AlertMessageListener, LogonListner {

    /** The next screen to be displayed */
    private Display currentDisplay;
    /** Username for a user */
    private String username;
    /** Password for a user */
    private String password;
    /** Input to put user password */
    private TextField passwordField;
    /** Display alerts */
    private AlertMessage alertMessage;
    /** Check if user is logged in */
    private boolean userLoggedOn = true;
    /** Reference to user service */
    private UserServiceImpl userService;
    private StorageListener eventListner;
    /** Reference to the report service */
    private ReportServiceImpl reportService;
    private Displayable prvScreen;
    private LogonListner logonListner;

    public LoginForm(Display currentDisplay) {
        super(TextPool.TITLE());
        setCurrentDisplay(currentDisplay);
        setLogonListner(this);
        setPrvScreen(this);
        createLoginForm();
        openDb();
    }

    /**
     * 
     */
    private void openDb() {
        userService = new UserServiceImpl();
    }

    /**
     * Creates the widgets on the login form.
     */
    private void createLoginForm() {
        passwordField = new TextField(TextPool.PASSWORD(), null, 4, TextField.NUMERIC | TextField.PASSWORD);

        this.append("Service Report\n");
        this.append(passwordField);

        this.addCommand(CommandPool.btnLogin);
        this.addCommand(CommandPool.btnExit);
        setCommandListener(this);

        getCurrentDisplay().setCurrent(this);
    }

    public void commandAction(Command btn, Displayable nxtScreen) {
        if (btn.equals(CommandPool.btnLogin)) {
            setPassword(passwordField.getString().trim());
            if (getPassword().equals(TextPool.EMPTY_STRING()) || getPassword().length() == 0) {
                alertMessage = new AlertMessage(getCurrentDisplay(), TextPool.TITLE(), this, this);
                alertMessage.show(TextPool.EMPTY_PASSWORD());
            } else {
                validateUser(getPassword());
            }
        }

        if (btn.equals(CommandPool.btnExit)) {
            setUserLoggedOn(false);
            try {
                userService.closeDB();
                userService.cleanDbUp();
                userService = null;
                cleanUp();

            } catch (Exception e) {
                e.printStackTrace();
            }
            Report4Service.exitMIDlet();
        }
    }

    private void cleanUp() {
        currentDisplay = null;
        username = TextPool.EMPTY_STRING();
        password = TextPool.EMPTY_STRING();
        alertMessage = null;
        userLoggedOn = false;
        eventListner = null;
        reportService = null;
        prvScreen = null;
        logonListner = null;
    }

    /**
     * Valid if its the right user accessing the application
     */
    private void validateUser(String password) {
        User user = userService.getUser();
        if (user != null) {
            if (user.getPassword().equals(password.trim())) {
                passwordField.setString(TextPool.EMPTY_STRING());
                userService.shutDB();
                reportService = new ReportServiceImpl();
                new CalenderForm(getCurrentDisplay(), this, TextPool.TITLE(), this, userService, reportService);
            } else {
                    alertMessage = new AlertMessage(getCurrentDisplay(), TextPool.TITLE(), this, this);
                    alertMessage.show(TextPool.INVALID_PASSWORD());
                
            }
        }
    }

    public void onAlertMessage(byte msg) {
        if (msg == AlertMessageListener.MSG_OK) {
            passwordField.setString(TextPool.EMPTY_STRING());
            getCurrentDisplay().setCurrent(this);
        } else {
            alertMessage.turnOffAlert();
        }
    }

    /**
     * @return the currentDisplay
     */
    public Display getCurrentDisplay() {
        return currentDisplay;
    }

    /**
     * @param currentDisplay
     *            the currentDisplay to set
     */
    public void setCurrentDisplay(Display currentDisplay) {
        this.currentDisplay = currentDisplay;
    }

    /**
     * @return the username
     */
    public String getUsername() {
        return username;
    }

    /**
     * @param username
     *            the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password
     *            the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * @return the passwordField
     */
    public TextField getPasswordField() {
        return passwordField;
    }

    /**
     * @param passwordField
     *            the passwordField to set
     */
    public void setPasswordField(TextField passwordField) {
        this.passwordField = passwordField;
    }

    /**
     * @return the alertMessage
     */
    public AlertMessage getAlertMessage() {
        return alertMessage;
    }

    /**
     * @param alertMessage
     *            the alertMessage to set
     */
    public void setAlertMessage(AlertMessage alertMessage) {
        this.alertMessage = alertMessage;
    }

    /**
     * @return the loggedOn
     */
    public boolean isLoggedOn() {
        return userLoggedOn;
    }

    /**
     * @param loggedOn
     *            the loggedOn to set
     */
    public void setLoggedOn(boolean userLoggedOn) {
        this.userLoggedOn = userLoggedOn;
    }

    public boolean onLoggedOn() {
        return isLoggedOn();
    }

    public void onLogonCancel() {
        setLoggedOn(false);
    }

    /**
     * @return the userLoggedOn
     */
    public boolean isUserLoggedOn() {
        return userLoggedOn;
    }

    /**
     * @param userLoggedOn
     *            the userLoggedOn to set
     */
    public void setUserLoggedOn(boolean userLoggedOn) {
        this.userLoggedOn = userLoggedOn;
    }

    public StorageListener getEventListner() {
        return eventListner;
    }

    public void setEventListner(StorageListener eventListner) {
        this.eventListner = eventListner;
    }

    public LogonListner getLogonListner() {
        return logonListner;
    }

    public void setLogonListner(LogonListner logonListner) {
        this.logonListner = logonListner;
    }

    public Displayable getPrvScreen() {
        return prvScreen;
    }

    public void setPrvScreen(Displayable prvScreen) {
        this.prvScreen = prvScreen;
    }

    public ReportServiceImpl getReportService() {
        return reportService;
    }

    public void setReportService(ReportServiceImpl reportService) {
        this.reportService = reportService;
    }

    public UserServiceImpl getUserService() {
        return userService;
    }

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }
}
